mod config;
mod error;
mod executor;
mod extend;
mod flow_run;
mod flow_run_step;
mod utils;
pub use config::{init_workflow_config,get_workflow_config,get_workflow_newest_config};
pub use flow_run::*;
use shq_common::prelude::{get_my_pool, FlowRunProps, TaskDoing, TaskType};
use sqlx::Row;

use crate::executor::cache::FlowCache;
pub async fn get_flow_run_props(run_id:u64) -> anyhow::Result<FlowRunProps> {
    let mut fc=FlowCache::from(run_id)?;
    let fi=fc.get_flow_info().await?;
    Ok(fi.into())
}

pub async fn get_task_list(user_id: u32) -> anyhow::Result<Vec<TaskDoing>> {
    let sql="SELECT wfid,num FROM task_list WHERE emid = ?";
    let rows= sqlx::query(sql)
        .bind(user_id)
        .fetch_all(get_my_pool()).await?;
    let mut tasks=Vec::new();
    for row in rows {
        let wfid: u32 = row.try_get("wfid")?;
        let num: i64 = row.try_get("num")?;
        let (wf_conf,_)=get_workflow_newest_config(wfid).ok_or(anyhow::anyhow!("Workflow config not found"))?;
        let name = wf_conf.name.to_owned();
        tasks.push(TaskDoing { wfid, name, count: num as u32, perm_id: wf_conf.perm_id });
    }
    Ok(tasks)
}
pub fn get_where_clause(user_id: u32, task_type: TaskType) -> String {
    let flow_state: &str = match task_type {
        TaskType::Doing => "0",
        TaskType::Done => "0",
        TaskType::Completed => "1",
        TaskType::Suspended => "2", // Adding missing match arm
        TaskType::Manager => "0,2", // Adding missing match arm
    };
    // 0：未办，1：在办，2：提交，3：退回，4:中止
    let step_state: &str = match task_type {
        TaskType::Doing => "1",
        TaskType::Done => "2,3",
        TaskType::Completed => "2",
        TaskType::Suspended => "4",
        TaskType::Manager => "0,1,2,3,4",
    };
    let flow_table_name = match task_type {
        TaskType::Completed => "flow_run_his",
        _ => "flow_run",
    };
    let step_table_name = match task_type {
        TaskType::Completed => "flow_run_step_his",
        _ => "flow_run_step",
    };
    if task_type == TaskType::Manager {
        return format!("frid in (select run_id from {flow_table_name} where state in ({flow_state}))");
    }
    format!(r#"frid in (select run_id from {flow_table_name} where state in ({flow_state})) and
    frid in (select run_id from {step_table_name} where state in ({step_state}) and emid={user_id})"#)
}

#[cfg(test)]
mod tests {

    use super::*;
    use shq_common::prelude::{FlowState, SubmitType};
    use tracing_subscriber::{filter::LevelFilter, prelude::*};
    #[tokio::test]
    async fn create_test() {
        dotenv::dotenv().ok();
        shq_common::prelude::init_app_config().await.unwrap();
        init_workflow_config().await.unwrap();
        let res = create(1, 200).await;
        match res {
            Ok(run_id) => assert_eq!(run_id, 1),
            Err(err) => panic!("create error:{err}"),
        }
        let res = create(1, 689).await;
        match res {
            Ok(run_id) => assert_eq!(run_id, 2),
            Err(err) => panic!("create error:{err}"),
        }
    }
    #[tokio::test]
    async fn test1() {
        dotenv::dotenv().ok();
        let stdout_log = tracing_subscriber::fmt::layer().pretty();
        tracing_subscriber::registry()
            .with(stdout_log.with_filter(LevelFilter::TRACE))
            .init();
        shq_common::prelude::init_app_config().await.unwrap();
        init_workflow_config().await.unwrap();
        let run_id = 3;
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 1);
        // submit(run_id, 200, SubmitType::SendNext, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 2);
        // submit(run_id, 268, SubmitType::SendNext, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 3);
        // submit(run_id, 1584, SubmitType::SendNext, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 3);
        // submit(run_id, 1075, SubmitType::Suspend, Some("不同意".to_string())).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.state, FlowState::Suspended);
        // submit(run_id, 1084, SubmitType::Activate, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.state, FlowState::Runing);
        submit(run_id, 1084, SubmitType::Completed, None)
            .await
            .unwrap();
        let run_proc = get_process(run_id).await.unwrap();
        assert_eq!(run_proc.state, FlowState::Completed);
    }
    #[tokio::test]
    async fn test2() {
        dotenv::dotenv().ok();
        let stdout_log = tracing_subscriber::fmt::layer().pretty();
        tracing_subscriber::registry()
            .with(stdout_log.with_filter(LevelFilter::TRACE))
            .init();
        shq_common::prelude::init_app_config().await.unwrap();
        init_workflow_config().await.unwrap();
        let run_id = 71;
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 1);
        // submit(run_id, 689, SubmitType::SendNext, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 2);
        // let res=submit(run_id, 689, SubmitType::SendNext, None).await;
        // assert!(res.is_err());
        // submit(run_id, 6, SubmitType::SendBack(1), Some("不同意".to_owned())).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 1);
        // submit(run_id, 689, SubmitType::SendNext, None).await.unwrap();
        // let run_proc=get_process(run_id).await.unwrap();
        // assert_eq!(run_proc.curr_step, 2);
        submit(run_id, 102, SubmitType::SendBack, None).await.unwrap();
        let run_proc = get_process(run_id).await.unwrap();
        assert_eq!(run_proc.curr_step, 3);
        assert_eq!(run_proc.state, FlowState::Runing);
    }
}

// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 1);
// submit(run_id, user_id, SubmitType::SendNext, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 2);
// submit(run_id, user_id, SubmitType::TakeBack, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 1);
// submit(run_id, user_id, SubmitType::SendNext, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 2);
// let res=submit(run_id, user_id, SubmitType::SendNext, None,false).await;
// assert!(res.is_err());
// submit(run_id, 268, SubmitType::SendBack(1), Some("不同意".to_owned()),false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 1);
// submit(run_id, 200, SubmitType::SendNext, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 2);
// submit(run_id, 268, SubmitType::TakeBack, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 2);
// submit(run_id, 268, SubmitType::SendNext, None,false).await.unwrap();
// let run_proc=get_process(run_id).await.unwrap();
// assert_eq!(run_proc.curr_step, 3);
